package com.xiaoye.qbdatahandle.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mongodb.client.result.UpdateResult;
import com.xiaoye.qbdatahandle.config.XiaoYeConfig;
import com.xiaoye.qbdatahandle.domian.AjaxResult;
import com.xiaoye.qbdatahandle.domian.AnalysisResult;
import com.xiaoye.qbdatahandle.domian.CollectionResult;
import com.xiaoye.qbdatahandle.domian.QbSubjectArticle;
import com.xiaoye.qbdatahandle.entity.ImageEntity;
import com.xiaoye.qbdatahandle.service.FileDownloadService;
import com.xiaoye.qbdatahandle.service.TextAnalyzerService;
import com.xiaoye.qbdatahandle.util.MongoUtil;
import com.xiaoye.qbdatahandle.vo.ExportArticleVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.Index;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 专题文章  清洗后的
 */
@Slf4j
@RestController
@RequestMapping("/subjectArticle")
public class QbSubjectArticleController {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    FileDownloadService fileDownloadService;
    @Autowired
    TextAnalyzerService textAnalyzerService;

    @GetMapping("/list")
    public AjaxResult list(@RequestParam int page,
                           @RequestParam int size, ExportArticleVo vo) {
        page = MongoUtil.getModalPn(page);
        Criteria criteria = new Criteria();
        // 标题模糊查询
        if (StringUtils.isNotBlank(vo.getTitle())) {
            criteria.and("title").regex(MongoUtil.getLike(vo.getTitle()));
        }
        // 关键词模糊查询
        if (StringUtils.isNotBlank(vo.getKeywords())) {
            criteria.and("keywords").regex(MongoUtil.getLike(vo.getKeywords()));
        }
        if (StringUtils.isNotBlank(vo.getTid())) {
            criteria.and("_tid").is(new ObjectId(vo.getTid()));
        }
        // 根据时间范围查询
        LocalDateTime startTime = vo.getStartTime();
        LocalDateTime endTime = vo.getEndTime();
        if (startTime != null && endTime != null) {
            criteria.and("publish_time").gte(startTime)
                    .lte(endTime);
        }
        Query query = Query.query(criteria);
        // 创建分页参数
        Pageable pageable = PageRequest.of(page, size);
        long count = mongoTemplate.count(query, QbSubjectArticle.class);
        mongoTemplate.indexOps(QbSubjectArticle.class).ensureIndex(new Index().on("publish_time", Sort.Direction.DESC));
        query.with(Sort.by(Sort.Order.desc("publish_time"))).skip((long) page * size).limit(size);
        List<QbSubjectArticle> list = mongoTemplate.find(query.with(pageable), QbSubjectArticle.class);
        IPage<QbSubjectArticle> pages = MongoUtil.getModalIPage(page, size, count, list);
        return AjaxResult.success(pages);
    }

    @GetMapping("/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id) {
        QbSubjectArticle qbSubjectArticle = mongoTemplate.findById(id, QbSubjectArticle.class);
        if (qbSubjectArticle == null) {
            return AjaxResult.error("文章不存在");
        }
        return AjaxResult.success(qbSubjectArticle);
    }

    @PostMapping
    public AjaxResult add(@RequestBody QbSubjectArticle qbSubjectArticle) {
        qbSubjectArticle.setCreateTime(DateUtil.now());
        qbSubjectArticle.setUpdateTime(DateUtil.now());
        mongoTemplate.insert(qbSubjectArticle);
        return AjaxResult.success();
    }

    @PutMapping()
    public AjaxResult edit(@RequestBody QbSubjectArticle qbSubjectArticle) {
        // 更新文章
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(qbSubjectArticle.getId()));
        Update update = new Update();
        update.set("title", qbSubjectArticle.getTitle());
        String keywords = qbSubjectArticle.getKeywords();
        if (StringUtils.isNotBlank(keywords)) {
            update.set("keywords", keywords);
        }
        String content = qbSubjectArticle.getContent();
        if (StringUtils.isNotBlank(content)) {
            update.set("content", content);
        }
        String intro = qbSubjectArticle.getIntro();
        if (StringUtils.isNotBlank(intro)) {
            update.set("intro", intro);
        }
        String cover = qbSubjectArticle.getCover();
        if (StringUtils.isNotBlank(cover)) {
            update.set("cover", cover);
        }
        String publishTime = qbSubjectArticle.getPublishTime();
        if (publishTime != null) {
            update.set("publish_time", publishTime);
        }
        String source = qbSubjectArticle.getSource();
        if (StringUtils.isNotBlank(source)) {
            update.set("source", source);
        }
        update.set("update_time", new Date());
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, QbSubjectArticle.class);
        return AjaxResult.success(updateResult.getMatchedCount());
    }

    @DeleteMapping("/{id}")
    public AjaxResult delete(@PathVariable("id") String id) {
        Criteria criteria = Criteria.where("id").is(id);
        mongoTemplate.remove(new Query(criteria), QbSubjectArticle.class);
        return AjaxResult.success();
    }

    /**
     * @description: 导出文章数据
     * @author: ChenYao
     * @return: void
     * @ceateDate: 2025/2/27 上午3:27
     */
    @PostMapping("/export")
    public void export(@RequestBody ExportArticleVo exportArticleVo, HttpServletResponse response) {
        List<String> filePaths = new ArrayList<>();
        List<String> ids = exportArticleVo.getIds();
        String title = exportArticleVo.getTitle();
        // 根据标题模糊查询
        Criteria criteria = new Criteria();
        if (StringUtils.isNotBlank(title)) {
            criteria.and("title").regex(MongoUtil.getLike(title));
        }
        // 根据id查询
        if (ids != null && !ids.isEmpty()) {
            criteria.and("id").in(ids);
        }
        // 根据时间范围查询
        LocalDateTime startTime = exportArticleVo.getStartTime();
        LocalDateTime endTime = exportArticleVo.getEndTime();
        if (startTime != null && endTime != null) {
            criteria.and("publish_time").gte(MongoUtil.getModalTime(startTime))
                    .lte(MongoUtil.getModalTime(endTime));
        }

        // 查询 所有文章数据
        List<QbSubjectArticle> list = mongoTemplate.find(new Query(criteria), QbSubjectArticle.class);
        if (list.isEmpty()) {
            log.info("查询文章数据为空");
            return;
        }
        list.forEach(article -> {
            // 查询文章 摘要 实体识别
            AnalysisResult analysisResult = mongoTemplate.findOne(new Query(Criteria.where("collect_result_id").is(article.getCollectionResultId())), AnalysisResult.class);
            if (analysisResult != null) {
                article.setElementInfo(analysisResult.getElementInfo());
                article.setIntro(analysisResult.getIntro());
            }


            // 导出文章图片
            List<ImageEntity> images = article.getImages();
            if (images == null || images.isEmpty()) {
                return;
            }
            StringBuffer contentImages = new StringBuffer();
            images.forEach(image -> {
                try {
                    String filename = image.getFilename();
                    if (StringUtils.isBlank(filename)) {
                        return;
                    }
                    //File file = new File(XiaoYeConfig.getProfile() + File.separator + filename);
                    File file = new File(filename);
                    log.info("下载路径:{}", file.getAbsolutePath());
                    fileDownloadService.downloadLargeFile(XiaoYeConfig.getImageWeb() + filename, file.getAbsolutePath());
                    contentImages.append(filename).append("\n");
                    // 图片路径
                    filePaths.add(file.getAbsolutePath());
                } catch (IOException e) {
                    log.error("导出文章图片失败", e);
                } catch (Exception e) {
                    log.error("导出文章图片不存在或其他异常", e);
                }
            });
            article.setContentImages(contentImages.toString());
        });


        // 数据导出成excel
        //File excelFile = new File(XiaoYeConfig.getProfile() + File.separator +"article_" + UUID.fastUUID() + ".xlsx");
        File excelFile = new File("article_" + UUID.fastUUID() + ".xlsx");
        log.info("数据准备写入excel,getAbsolutePath:{}", excelFile.getAbsolutePath());
        // 写入 Excel
        try {
            EasyExcel.write(excelFile, QbSubjectArticle.class)
                    .sheet("article")
                    .doWrite(list);
            filePaths.add(excelFile.getAbsolutePath());
            downloadZip(filePaths, response);
            log.info("excel 生成完成");
        } catch (Exception e) {
            log.error("导出文章数据失败", e);

        }
    }

    /**
     * @param id
     * @description: 詞雲
     * @author: ChenYao
     * @return: com.xiaoye.qbdatahandle.domian.AjaxResult
     * @ceateDate: 2025/3/29 0:52
     */

    @GetMapping("/getWordFrequency/{id}")
    public AjaxResult getWordFrequency(@PathVariable("id") String id) {
        // 或者 采集结果内容
        QbSubjectArticle collectionresult = mongoTemplate.findById(id, QbSubjectArticle.class);
        if (collectionresult == null) {
            return AjaxResult.error("结果不存在");
        }
        String text = collectionresult.getContent();
        if (StringUtils.isBlank(text)) {
            return AjaxResult.error("内容为空");
        }
        // 获取词频数据
        Map<String, Integer> wordFrequency = textAnalyzerService.analyzeText(text);
        return AjaxResult.success(wordFrequency);
    }

    public void downloadZip(List<String> imagePaths, HttpServletResponse response) throws IOException {
        // 图片路径列表

        // 设置响应头
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=article_" + UUID.fastUUID() + ".zip");

        // 将 ZIP 文件写入响应输出流
        try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
            for (String imagePath : imagePaths) {
                try (FileInputStream fis = new FileInputStream(imagePath)) {
                    log.info("ZIP写入文件:{}", imagePath);
                    ZipEntry zipEntry = new ZipEntry(getFileName(imagePath));
                    zipOut.putNextEntry(zipEntry);
                    byte[] bytes = new byte[1024];
                    int length;
                    while ((length = fis.read(bytes)) >= 0) {
                        zipOut.write(bytes, 0, length);
                    }
                }
            }
        }
    }

    public static String getFileName(String filePath) {
        File file = new File(filePath);
        return file.getName();
    }
}
